// request.js - 网络请求封装

import { userStorage } from './storage';

/**
 * 自定义请求错误类
 */
export class RequestError extends Error {
  constructor(code, message) {
    super(message);
    this.code = code;
    this.message = message;
    this.name = 'RequestError';
  }
}

/**
 * 网络请求基础配置
 * 
 * 生产环境：使用相对路径（通过 nginx 代理）
 * 开发环境：设置环境变量 REACT_APP_API_BASE_URL
 */
const BASE_URL = process.env.REACT_APP_API_BASE_URL || '';
const TIMEOUT = 10000; // 请求超时时间（毫秒）

/**
 * 超时控制
 */
const timeoutPromise = (timeout) => {
  return new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error('请求超时'));
    }, timeout);
  });
};

/**
 * 清除认证信息并跳转到登录页
 */
const clearAuthAndRedirect = () => {
  // 清除所有认证相关的存储
  userStorage.clearUserInfo();
  
  // 跳转到登录页
  console.log('用户信息验证失败，清除认证信息并跳转到登录页');
  // 使用 window.location.href 确保完全跳转
  window.location.href = '/login';
};

/**
 * 请求拦截器 - 在请求发送前处理
 */
const requestInterceptor = (url, options = {}) => {
  // 统一验证用户信息（除了登录接口）
  const loginUrls = ['/user/login', '/login'];
  const isLoginRequest = loginUrls.some(loginUrl => url.includes(loginUrl));
  
  if (!isLoginRequest) {
    // 非登录请求，需要验证用户信息
    const isValid = userStorage.validateUserInfo();
    
    if (!isValid) {
      // 用户信息无效，清除数据并跳转到登录页
      clearAuthAndRedirect();
      // 抛出错误阻止请求继续
      throw new Error('用户未登录或信息无效，请重新登录');
    }
  }

  // 添加统一的请求头
  const headers = {
    'Content-Type': 'application/json',
    ...options.headers
  };

  // 添加 token（如果已登录）
  const token = localStorage.getItem('token');
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  return {
    ...options,
    headers
  };
};

/**
 * 响应拦截器 - 在响应返回后处理
 */
const responseInterceptor = async (response) => {
  // HTTP 状态码检查
  if (!response.ok) {
    throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
  }

  // 解析 JSON
  const data = await response.json();

  // 业务状态码检查（参考 care-spirit 小程序的错误码定义）
  if (data.code !== 10000) {
    throw new RequestError(data.code, data.message || '请求失败');
  }

  return data.data;
};

/**
 * 显示加载提示
 */
const showLoading = (message = '加载中...') => {
  // 可以集成 UI 库的 loading 组件
  // 这里暂时使用简单的实现
  const loadingEl = document.getElementById('global-loading');
  if (loadingEl) {
    loadingEl.style.display = 'flex';
    const textEl = loadingEl.querySelector('.loading-text');
    if (textEl) textEl.textContent = message;
  }
};

/**
 * 隐藏加载提示
 */
const hideLoading = () => {
  const loadingEl = document.getElementById('global-loading');
  if (loadingEl) {
    loadingEl.style.display = 'none';
  }
};

/**
 * 显示错误提示
 */
const showError = (message) => {
  // 可以集成 UI 库的 toast 组件
  // 这里使用简单的 alert
  alert(message);
};

/**
 * 统一的网络请求方法
 */
const request = async (url, options = {}) => {
  const {
    needLoading = true,
    loadingText = '加载中...',
    showErrorMsg = true,
    ...fetchOptions
  } = options;

  // 显示加载提示
  if (needLoading) {
    showLoading(loadingText);
  }

  try {
    // 请求拦截
    const interceptedOptions = requestInterceptor(url, fetchOptions);

    // 完整的 URL
    const fullUrl = url.startsWith('http') ? url : `${BASE_URL}${url}`;

    // 打印请求信息
    console.log('========================================');
    console.log('📤 发送请求');
    console.log('----------------------------------------');
    console.log('URL:', fullUrl);
    console.log('Method:', interceptedOptions.method || 'GET');
    console.log('Headers:', JSON.stringify(interceptedOptions.headers, null, 2));
    
    // 打印请求体（解析 JSON 使其易读）
    if (interceptedOptions.body) {
      try {
        const requestBody = JSON.parse(interceptedOptions.body);
        console.log('请求体:', JSON.stringify(requestBody, null, 2));
      } catch (e) {
        console.log('请求体:', interceptedOptions.body);
      }
    }

    // 发起请求（带超时控制）
    const response = await Promise.race([
      fetch(fullUrl, interceptedOptions),
      timeoutPromise(TIMEOUT)
    ]);

    // 克隆响应以便多次读取
    const responseClone = response.clone();

    // 打印原始响应信息
    console.log('----------------------------------------');
    console.log('📥 收到响应');
    console.log('Status:', response.status, response.statusText);

    // 响应拦截
    const result = await responseInterceptor(response);

    // 打印完整的响应体
    try {
      const rawResponse = await responseClone.json();
      console.log('响应体:', JSON.stringify(rawResponse, null, 2));
    } catch (e) {
      console.log('响应体: 无法解析为 JSON');
    }

    console.log('处理后的数据:', JSON.stringify(result, null, 2));
    console.log('========================================\n');

    // 隐藏加载提示
    if (needLoading) {
      hideLoading();
    }

    return result;

  } catch (error) {
    // 打印错误信息
    console.log('----------------------------------------');
    console.error('❌ 请求失败');
    console.error('错误类型:', error.name);
    console.error('错误消息:', error.message);
    if (error instanceof RequestError) {
      console.error('错误码:', error.code);
    }
    console.error('错误详情:', error);
    console.log('========================================\n');

    // 隐藏加载提示
    if (needLoading) {
      hideLoading();
    }

    // 显示错误提示
    if (showErrorMsg) {
      showError(error.message || '网络请求失败');
    }

    // 处理特殊错误码
    if (error instanceof RequestError) {
      // 401 未授权 - 跳转到登录页
      if (error.code === 401 || error.code === 10401) {
        console.log('Token 失效，清除认证信息并跳转到登录页');
        clearAuthAndRedirect();
      }
    }

    // 抛出错误供调用方处理
    throw error;
  }
};

/**
 * GET 请求
 */
export const get = (url, params = {}, options = {}) => {
  // 将参数拼接到 URL
  const queryString = Object.keys(params)
    .filter(key => params[key] !== undefined && params[key] !== null)
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
    .join('&');
  
  const fullUrl = queryString ? `${url}?${queryString}` : url;

  return request(fullUrl, {
    method: 'GET',
    ...options
  });
};

/**
 * POST 请求
 */
export const post = (url, data = {}, options = {}) => {
  return request(url, {
    method: 'POST',
    body: JSON.stringify(data),
    ...options
  });
};

/**
 * PUT 请求
 */
export const put = (url, data = {}, options = {}) => {
  return request(url, {
    method: 'PUT',
    body: JSON.stringify(data),
    ...options
  });
};

/**
 * DELETE 请求
 */
export const del = (url, params = {}, options = {}) => {
  const queryString = Object.keys(params)
    .filter(key => params[key] !== undefined && params[key] !== null)
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
    .join('&');
  
  const fullUrl = queryString ? `${url}?${queryString}` : url;

  return request(fullUrl, {
    method: 'DELETE',
    ...options
  });
};

/**
 * 导出默认对象
 */
export default {
  get,
  post,
  put,
  delete: del
};

